   // 这个是观察者的类
   const Observer = function (data) {
     // 循环修改为每个属性添加get set
     for (let key in data) {
       defineReactive(data, key);
     }
   }

   // 这个是响应式
   const defineReactive = function (obj, key) {
     // 局部变量dep，用于get set内部调用
     const dep = new Dep();
     // 获取当前值
     let val = obj[key];
     Object.defineProperty(obj, key, {
       // 设置当前描述属性为可被循环
       enumerable: true,
       // 设置当前描述属性可被修改
       configurable: true,
       get() {
         console.log('1');
         console.log('in get');
         // 调用依赖收集器中的addSub，用于收集当前属性与Watcher中的依赖关系
         dep.depend();
         return val;
       },
       set(newVal) {
         if (newVal === val) {
           return;
         }
         val = newVal;
         // 当值发生变更时，通知依赖收集器，更新每个需要更新的Watcher，
         // 这里每个需要更新通过什么断定？dep.subs
         dep.notify();
         console.log('5');
       }
     });
   }


   const observe = function (data) {
     return new Observer(data);
   }

   const Vue = function (options) {
     const self = this;
     // 将data赋值给this._data，源码这部分用的Proxy所以我们用最简单的方式临时实现
     if (options && typeof options.data === 'function') {
       this._data = options.data.apply(this);
     }
     // 挂载函数
     this.mount = function () {
       new Watcher(self, self.render);
     }
     // 渲染函数
     this.render = function () {
       with(self) {
         _data.text;
       }
     }
     // 监听this._data
     observe(this._data);
   }

   const Watcher = function (vm, fn) {
     const self = this;
     this.vm = vm;
     // 将当前Dep.target指向自己
     Dep.target = this;
     // 向Dep方法添加当前Wathcer
     this.addDep = function (dep) {
       console.log('3');
       console.log('会执行addDep');
       dep.addSub(self);
     }
     // 更新方法，用于触发vm._render
     this.update = function () {
       console.log('in watcher update');
       fn();
     }
     // 这里会首次调用vm._render，从而触发text的get
     // 从而将当前的Wathcer与Dep关联起来
     this.value = fn();
     // 这里清空了Dep.target，为了防止notify触发时，不停的绑定Watcher与Dep，
     // 造成代码死循环
     Dep.target = null;
   }

   const Dep = function () {
     const self = this;
     // 收集目标
     this.target = null;
     // 存储收集器中需要通知的Watcher
     this.subs = [];
     // 当有目标时，绑定Dep与Wathcer的关系
     this.depend = function () {
       if (Dep.target) {
         console.log('2');
         //这里调来调取还是把watcher存到subs
         //get -> depend -> watcher -> addSub -> subs
         // 这里其实可以直接写self.addSub(Dep.target)，源码为什么不是这样呢？
         // 没有这么写因为想还原源码的过程。
         console.log('会执行depend');
         Dep.target.addDep(self);
       }
     }
     // 为当前收集器添加Watcher
     this.addSub = function (watcher) {
       console.log('4');
       console.log('会执行addSub');
       self.subs.push(watcher);
     }
     // 通知收集器中所的所有Wathcer，调用其update方法
     this.notify = function () {
       for (let i = 0; i < self.subs.length; i += 1) {
         self.subs[i].update();
       }
     }
   }

   const vue = new Vue({
     data() {
       return {
         text: 'hello world'
       };
     }
   })

   vue.mount(); // in get
   vue._data.text = '123'; // in watcher update /n in get


   